package net.sourceforge.jweb.util;

/**
 * 
 * @author 毛安平
 *
 */
public class MathExtention {
	private MathExtention() {

	}

	/**
	 * 求两个数的最小公倍数
	 * 
	 * @param n1
	 *            整型数1
	 * @param n2
	 *            整型数2
	 * @return 两个数的最大公约数
	 */
	public static int GCD(int num1, int num2) {
		if (num2 == 0)
			return 1;
		int residue = num1 % num2;
		if (residue == 0)
			return num2;
		return GCD(num2, residue);
	}

	/**
	 * 找一个整型数组的最大公约数
	 * 
	 * @param value
	 *            一个整型的数组
	 * @return 最大公约数<br>
	 *         如果没有找到,将返回0
	 */
	public static int GCD(int[] value) {
		int min;
		int index = 0;
		int length = value.length;
		for (int i = 1; i < length; i++)
			if (value[i] < value[index])
				index = i;// 记住以找的最小的数的下标
		min = value[index];
		for (int i = min; i > 0; i--) {
			boolean isFound = true;
			for (int j = 0; j < value.length; j++) {
				if ((value[j] % i) != 0) {
					isFound = false;
					break;
				}
			}
			if (isFound)
				return i;
		}
		return 0;
	}

	/**
	 * 找一个整型数组的最大公约数
	 * 
	 * @param arrayInt
	 *            一个整型的数组
	 * @return 最大公约数<br>
	 *         如果没有找到,将返回0
	 */
	public static int GCD1(int[] arrayInt) {
		int length = arrayInt.length;
		if (length == 1)
			return arrayInt[0];
		if (length == 2)
			return GCD(arrayInt[0], arrayInt[1]);
		int temp = GCD(arrayInt[0], arrayInt[1]);
		for (int i = 2; i < length; i++) {
			temp = GCD(temp, arrayInt[i]);
		}
		return temp;
	}

	public static int LCM(int n1, int n2) {
		return (n1 * n2) / GCD(n1, n2);
	}

	public static int LCM(int divs[]) {
		if (divs.length == 1)
			return divs[0];
		int res = LCM(divs[0], divs[1]);
		for (int i = 2; i < divs.length; i++)
			res = LCM(res, divs[i]);
		return res;
	}

	/**
	 * 获得一个正整数可以被2整除几次
	 * 
	 * @param val
	 * @return
	 */
	public static int approximateLog2(int val) {
		if (val <= 0)
			return Integer.MIN_VALUE;
		int ret = 0;
		while (val != 1) {
			val >>= 1;
			ret++;
		}
		;
		return ret;
	}

	/**
	 * 求一个正整数能被x整除几次
	 * 
	 * @param val
	 *            被除数
	 * @param x
	 *            除数
	 * @return 正除结果
	 */
	public static int approximateLogx(int val, int x) {
		if (val <= x || val < 0 || x <= 0)
			return 0;
		if (x == 1)
			return val;
		int ret = 0;
		while (val >= x) {
			val /= x;
			ret++;
		}
		return ret;
	}

	/**
	 * 近似向上取整,如果小数部分大于0.1，则+1
	 */
	public static int approximateCeil(float value) {
		return (int) value;
	}

	public static boolean approximateEquals(float num1, float num2, float rest) {
		return StrictMath.abs(num1 - num2) < rest;
	}

	/**
	 * 已知直线上两点，和y，求x
	 * 
	 * @return
	 */
	public static float linearX(float x1, float y1, float x2, float y2, float y) {
		return ((x2 - x1) * (y - y1) + (y2 - y1) * x1) / (y2 - y1);
	}

	public static float min(float a, float b, float c) {
		return Math.min(Math.min(a, b), c);
	}

	public static float max(float a, float b, float c) {
		return Math.max(Math.max(a, b), c);
	}
	/*
	 * public static void main(String args[]){
	 * System.out.print(StrictMath.IEEEremainder(3.5, 2)); }
	 */
}
